package medOffice;

import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;

import medOffice.Enuns.EstadoDaConsulta;
import medOffice.Enuns.TipoDeConsulta;
import medOffice.Enuns.Urgencia;


/**
 * Classe que inicializa uma Consulta da clinica.
 * 
 * @author Francisco Demontie dos Santos Junior</br> <b>Matricula:</b> 20911084
 * @version 1.0, 03 de dezembro de 2009
 * 
 */
public class Consulta {

	private Paciente paciente;
	private Calendar data;
	private Urgencia urgencia;
	private TipoDeConsulta tipoDeConsulta = TipoDeConsulta.CONSULTA;
	private EstadoDaConsulta estadoDaConsulta = EstadoDaConsulta.NAO_ATENDIDO;
	

	
	/**
	 * Contrutor default
	 */
	public Consulta() {
		
	}
	
	/**
	 * Construtor da classe apenas com a data como parametro.
	 * @param Calendar data
	 * @throws Exception 
	 * 				lancada caso a data nao passe no teste do 
	 * 				seu verificador.
	 */
	public Consulta(Calendar data) throws Exception {
		if (Verificador.verificaDataFutura(data)) {
			setData(data);
			setHoraConsulta(new Time(data.getTimeInMillis()));
		}
		
	}
	
	/**
	 * Construtor mais completo.
	 * 
	 * @param Paciente
	 *             paciente da consulta
	 * @param Medico
	 *             medico do atendimento
	 * @param Calendar
	 *             data da consulta
	 * @param Enum
	 * 			   indica se a consulta eh ou nao urgente
	 * @throws Exception
	 *             caso um dos parametros passados seja invalido (paciente,
	 *             medico ou data nulos).
	 */
	public Consulta(Paciente paciente, Calendar data, Urgencia urgencia) throws Exception {
		if (paciente == null)
			throw new Exception("Paciente nao pode ser null");
		if (data == null)
			throw new Exception("Data nao pode ser null");

		this.paciente = paciente;
		this.data = data;
		this.urgencia = urgencia;
	}

	/**
	 * Metodo modificador que seta o Paciente.
	 * 
	 * @param Paciente
	 *             o novo paciente da consulta
	 */
	public void setPaciente(Paciente paciente) {
		if (paciente != null)
			this.paciente = paciente;
	}

	/**
	 * Metodo acessador que retorna o paciente da consulta.
	 * 
	 * @return Paciente
	 * 			 	paciente da consulta
	 */
	public Paciente getPaciente() {
		return this.paciente;
	}

	/**
	 * Metodo modificador que seta a data da consulta.
	 * @param Calendar
	 * 				nova data
	 */
	public void setData(Calendar data) {
		if (data != null && !Verificador.verificaDataPassada(data))
			this.data = data;
	}

	/**
	 * Metodo acessador que retorna um Calendar com a data da consulta.
	 * 
	 * @return Calendar
	 * 				 data da consulta
	 */
	public Calendar getData() {
		return this.data;
	}

	/**
	 * Metodo modificador que seta o tipo de consulta.
	 * 
	 * @param TipoDeConsulta
	 *             enum: CONSULTA ou RETORNO
	 */
	public void setTipoDeConsulta(TipoDeConsulta tipo) {
		if (tipo != null)
			this.tipoDeConsulta = tipo;
	}

	/**
	 * Metodo acessador que retorna o tipo da consulta.
	 * 
	 * @return TipoDeConsulta
	 */
	public TipoDeConsulta getTipoDeConsulta() {
		return this.tipoDeConsulta;
	}

	/**
	 * Metodo modificador que seta o estado da consulta.
	 * 
	 * @param EstadoDaConsulta
	 *             enum: ATENDIDO, NAO_ATENDIDO ou EM_ESPERA
	 */
	public void setEstadoDaConsulta(EstadoDaConsulta estado) {
		if (estado != null)
			this.estadoDaConsulta = estado;
	}

	/**
	 * Metodo acessador que retorna o estado da consulta.
	 * 
	 * @return EstadoDaConsulta
	 */
	public EstadoDaConsulta getEstadoDaConsulta() {
		return this.estadoDaConsulta;
	}
	
	
	/**
	 * Metodo acessador que retorna a hora da consulta.
	 * @return Time hora
	 */
	public Time getHoraConsulta() {
		return new Time(data.getTimeInMillis());
		
	}

	
	/**
	 * Metodo modificador que seta a hora da consulta
	 * @param Time hora da consulta
	 * @throws Exception 
	 * 				lancada quando a hora passada como parametro
	 * 				e nula.
	 */
	public void setHoraConsulta(Time horaConsulta) throws Exception {
		if(horaConsulta == null)
			throw new Exception("Parametro time null");
		
		Calendar horas = new GregorianCalendar();
		horas.setTimeInMillis(horaConsulta.getTime());
		
		getData().set(Calendar.HOUR_OF_DAY, horas.get(Calendar.HOUR_OF_DAY));
		getData().set(Calendar.MINUTE, horas.get(Calendar.MINUTE));
	}


	/**
	 * Metodo modificador que seta a urgencia da consulta.
	 * 
	 * @param Enum Urgencia
	 * 				 	S ou N
	 */
	public void setUrgencia(Urgencia urgente) {
		this.urgencia = urgente;
	}

	/**
	 * Metodo acessador que retorna a urgencia da consulta.
	 * 
	 * @return Enum
	 * 			 Urgencia
	 */
	public Urgencia getUrgencia() {
		return this.urgencia;
	}
	
	/**
	 * Metodo que retorna se a consulta e urgente.
	 * (usado para manter o encapsulamento).
	 * @return boolean True se a consulta e urgente, False caso
	 * contrario.
	 */
	public boolean heUrgencia(){
		return getUrgencia().equals(Urgencia.S);
	}
	
	/**
	 * Metodo acessador que retorna o valor da consulta.
	 * @return Double valor da consulta
	 */
	public double getValor(){
		return getTipoDeConsulta().equals(TipoDeConsulta.CONSULTA)? 
				getPaciente().getPlanoDeSaude().getValorConsulta():
					getPaciente().getPlanoDeSaude().getValorRetorno();
	}
	
	/**
	 * Metodo que verifica se um paciente ja foi atendido.
	 * @return boolean True caso ja tenha sido atendido, False caso contrario.
	 */
	public boolean foiAtendida(){
		return getEstadoDaConsulta().equals(EstadoDaConsulta.ATENDIDO);
	}
	
	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof Consulta))
			return false;
		Consulta outra = (Consulta) obj;
		return this.getData().equals(outra.getData());
		//		&& this.getData().equals(outra.getData());
	}

	@Override
	public String toString() {
		return "Paciente: "
				+ this.getPaciente().getNome()
				+ "Data: "
				+ new SimpleDateFormat("dd/MM/yyyy HH:mm").format(this
						.getData().getTime());
	}
}
